package com.kefu.chat.service;

import java.io.File;
import java.io.FileInputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.kefu.chat.model.ChatAdmin;
import com.kefu.chat.model.ChatChannel;
import com.kefu.chat.model.ChatUser;
import com.kefu.chat.util.ChatConstant;
import com.kefu.chat.vo.ChatUserParam.UserConnectP;
import com.kefu.chat.vo.ChatUserParam.UserConnectR;
import com.kefu.chat.vo.ChatUserParam.UserRobotAskP;
import com.kefu.chat.vo.ChatUserParam.UserRobotAskR;
import com.kefu.chat.vo.ChatUserParam.UserSendMsgP;
import com.kefu.common.multipart.IMultipartProvider;
import com.kefu.common.multipart.MultiPart;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Singleton;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HtmlUtil;
import me.chanjar.weixin.common.api.WxConsts;
import me.chanjar.weixin.common.bean.result.WxMediaUploadResult;
import me.chanjar.weixin.common.error.WxErrorException;
import me.chanjar.weixin.mp.api.WxMpService;
import me.chanjar.weixin.mp.api.impl.WxMpServiceImpl;
import me.chanjar.weixin.mp.bean.kefu.WxMpKefuMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlMessage;
import me.chanjar.weixin.mp.bean.message.WxMpXmlOutMessage;
import me.chanjar.weixin.mp.bean.result.WxMpUser;
import me.chanjar.weixin.mp.config.impl.WxMpDefaultConfigImpl;

@Service
public class ChatWxService {

    protected Logger logger = LoggerFactory.getLogger(getClass());
    @Autowired
    private ChatChannelService chatChannelService;
    @Autowired
    private ChatUserService chatUserService;
    @Autowired
    private ChatRobotService chatRobotService;
    @Autowired
    private ChatCacheService chatCacheService;
    @Autowired
    private IMultipartProvider multipartProvider;


     
    public WxMpService getWxMpService(String appId) {
        ChatChannel channel = chatChannelService.getFromAppId(appId);
        WxMpService wxService = Singleton.get(WxMpServiceImpl.class);
        WxMpDefaultConfigImpl config = new WxMpDefaultConfigImpl();
        config.setAppId(channel.getAppId());
        config.setSecret(channel.getAppSecret());
        config.setToken(channel.getAppToken());
        config.setAesKey(channel.getAesKey());
        wxService.addConfigStorage(appId, config);
        return wxService.switchoverTo(appId);
    }

     
    public WxMpXmlOutMessage eventHandle(String appId, WxMpXmlMessage inMessage) {
        logger.info("wx_eventHandle:{}", inMessage);
        return null;
    }

     
    public WxMpXmlOutMessage msgHandle(String appId, WxMpXmlMessage inMessage) {
        try {
            ChatChannel channel = chatChannelService.getFromAppId(appId);
            if (channel == null) return null;
            WxMpXmlOutMessage outMessage = null;
            int receiveMode = channel.getReceiveMode();
            String tenantId = channel.getTenantId();
            String userPid = inMessage.getFromUser();
            String userId = SecureUtil.md5(tenantId + userPid);
            String msgType = inMessage.getMsgType();
            String content = inMessage.getContent();
            boolean robotAsk = false;
            boolean adminConnect = false;
            boolean adminMsg = false;
            ChatUser user = chatCacheService.getUser(userId);
            if (user == null || user.getStatus() == ChatConstant.user_status_offline) {
                ChatUser newUser = new ChatUser();
                newUser.setSessionId(IdUtil.simpleUUID());
                newUser.setUserId(userId);
                newUser.setPid(userPid);
                newUser.setTenantId(tenantId);
                newUser.setChannelId(channel.getChannelId());
                newUser.setChannelType(ChatConstant.channel_type_wx);
                newUser.setChannelName(channel.getChannelName());
                newUser.setAppId(appId);
                newUser.setUserName("微信客户");
                try {
                    WxMpService wxMpService = getWxMpService(appId);
                    WxMpUser wxMpUser = wxMpService.getUserService().userInfo(userPid);
//                    newUser.setUserName(wxMpUser.getNickname());
//                    newUser.setUserFace(wxMpUser.getHeadImgUrl());
                    logger.info("wxMpUser:{}", wxMpUser);
                } catch (WxErrorException e) {
                    e.printStackTrace();
                }
                if (user != null) {
                    newUser.setPhone(user.getPhone());
                    newUser.setEmail(user.getEmail());
                    newUser.setCustomerId(user.getCustomerId());
                    newUser.setLastAdminId(user.getAdminId());
                    newUser.setUserFormMode(user.getUserFormMode());
                }
                user = newUser;
                chatCacheService.setUser(user);
                if (receiveMode == ChatConstant.chat_receive_robot_first || receiveMode == ChatConstant.chat_receive_robot_only) {
                    robotAsk = true;
                } else if (receiveMode == ChatConstant.chat_receive_admin_first || receiveMode == ChatConstant.chat_receive_admin_only) {
                    adminConnect = true;
                }
            } else if (user.getStatus() == ChatConstant.user_status_robot) {
                robotAsk = true;
            } else if (user.getStatus() == ChatConstant.user_status_wait) {
                if (receiveMode != ChatConstant.chat_receive_admin_only) {
                    robotAsk = true;
                }
            } else if (user.getStatus() == ChatConstant.user_status_online) {
                adminMsg = true;
            }
            if ("人工".equals(content) || "转人工".equals(content)) {
                if ((user.getStatus() == ChatConstant.user_status_offline || user.getStatus() == ChatConstant.user_status_robot) && receiveMode != ChatConstant.chat_receive_robot_only) {
                    adminConnect = true;
                }
            }
            if (adminConnect) {
                UserConnectP connectParam = new UserConnectP();
                connectParam.setUserId(userId);
                UserConnectR connectResult = chatUserService.connect(connectParam);
                if (connectResult.getStatus() == 1) {
                    if (receiveMode == ChatConstant.chat_receive_admin_only) {
                        outMessage = WxMpXmlOutMessage.TEXT().content(channel.getAdminOfflineMsg()).fromUser(inMessage.getToUser()).toUser(inMessage.getFromUser()).build();
                        return outMessage;
                    } else {
                        robotAsk = true;
                    }
                }
                if (connectResult.getStatus() == 2) {
                    adminMsg = true;
                }
                if (connectResult.getStatus() == 3) {
                    if (receiveMode != ChatConstant.chat_receive_admin_only) {
                        robotAsk = true;
                    }
                }
            }
            if (adminMsg) {
                try {
                    WxMpService wxMpService = getWxMpService(appId);
                    UserSendMsgP msgParam = new UserSendMsgP();
                    msgParam.setUserId(userId);
                    if (WxConsts.XmlMsgType.TEXT.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_text);
                        msgParam.setMsgContent(content);
                    } else if (WxConsts.XmlMsgType.LOCATION.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_text);
                        msgParam.setMsgContent(inMessage.getLabel());
                    } else if (WxConsts.XmlMsgType.LINK.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_text);
                        msgParam.setMsgContent(inMessage.getUrl());
                    } else if (WxConsts.XmlMsgType.IMAGE.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_image);
                        File file = wxMpService.getMaterialService().mediaDownload(inMessage.getMediaId());
                        MultiPart multiPart = multipartProvider.upload(new FileInputStream(file), "wx", tenantId, "jpg");
                        msgParam.setMsgContent(multiPart.getUrl());
                    } else if (WxConsts.XmlMsgType.VOICE.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_voice);
                        File file = wxMpService.getMaterialService().mediaDownload(inMessage.getMediaId());
                        MultiPart multiPart = multipartProvider.upload(new FileInputStream(file), "wx", tenantId, "mp3");
                        msgParam.setMsgContent(multiPart.getUrl());
                    } else if (WxConsts.XmlMsgType.VIDEO.equals(msgType) || WxConsts.XmlMsgType.SHORTVIDEO.equals(msgType)) {
                        msgParam.setMsgType(ChatConstant.chat_msg_type_video);
                        File file = wxMpService.getMaterialService().mediaDownload(inMessage.getMediaId());
                        MultiPart multiPart = multipartProvider.upload(new FileInputStream(file), "wx", tenantId, "mp4");
                        msgParam.setMsgContent(multiPart.getUrl());
                    } else {
                        outMessage = WxMpXmlOutMessage.TEXT().content("【不支持的消息类型】").fromUser(inMessage.getToUser()).toUser(inMessage.getFromUser()).build();
                        return outMessage;
                    }
                    chatUserService.sendMsg(msgParam);
                    return null;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            if (robotAsk) {
                if (WxConsts.XmlMsgType.TEXT.equals(msgType)) {
                    UserRobotAskP robotParam = new UserRobotAskP();
                    robotParam.setUserId(userId);
                    robotParam.setRobotNo(channel.getRobotNo());
                    robotParam.setQuestion(content);
                    UserRobotAskR robotResult = chatRobotService.userRobotAsk(robotParam);
                    StringBuilder robotAnswer = new StringBuilder();
                    if (StrUtil.isNotBlank(robotResult.getAnswer())) {
                        robotAnswer.append(robotResult.getAnswer());
                    }
                    for (int i = 0; i < robotResult.getSuggestList().size(); i++) {
                        robotAnswer.append("\n").append(i + 1).append(".").append(robotResult.getSuggestList().get(i).getQuestion());
                    }
                    outMessage = WxMpXmlOutMessage.TEXT().content(HtmlUtil.cleanHtmlTag(robotAnswer.toString())).fromUser(inMessage.getToUser()).toUser(inMessage.getFromUser()).build();
                } else {
                    outMessage = WxMpXmlOutMessage.TEXT().content(channel.getRobotUnknownMsg()).fromUser(inMessage.getToUser()).toUser(inMessage.getFromUser()).build();
                }
                return outMessage;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

     
    public String sendMsg(ChatAdmin admin, ChatUser user, int msgType, String msgContent) {
        try {
            WxMpService wxMpService = getWxMpService(user.getAppId());
            WxMpKefuMessage message = new WxMpKefuMessage();
            message.setToUser(user.getPid());
            if (msgType == ChatConstant.chat_msg_type_text) {
                message.setContent(HtmlUtil.cleanHtmlTag(msgContent));
                message.setMsgType(WxConsts.KefuMsgType.TEXT);
                wxMpService.getKefuService().sendKefuMessage(message);
            } else if (msgType == ChatConstant.chat_msg_type_image) {
                String path = multipartProvider.getPath(msgContent);
                WxMediaUploadResult uploadResult = wxMpService.getMaterialService().mediaUpload(WxConsts.KefuMsgType.IMAGE, "jpg", FileUtil.getInputStream(path));
                message.setMediaId(uploadResult.getMediaId());
                message.setMsgType(WxConsts.KefuMsgType.IMAGE);
                wxMpService.getKefuService().sendKefuMessage(message);
            } else if (msgType == ChatConstant.chat_msg_type_voice) {
                String path = multipartProvider.getPath(msgContent);
                WxMediaUploadResult uploadResult = wxMpService.getMaterialService().mediaUpload(WxConsts.KefuMsgType.VOICE, "mp3", FileUtil.getInputStream(path));
                message.setMediaId(uploadResult.getMediaId());
                message.setMsgType(WxConsts.KefuMsgType.VOICE);
                wxMpService.getKefuService().sendKefuMessage(message);
            } else if (msgType == ChatConstant.chat_msg_type_video) {
                String path = multipartProvider.getPath(msgContent);
                WxMediaUploadResult uploadResult = wxMpService.getMaterialService().mediaUpload(WxConsts.KefuMsgType.VIDEO, "mp4", FileUtil.getInputStream(path));
                message.setMediaId(uploadResult.getMediaId());
                message.setMsgType(WxConsts.KefuMsgType.VIDEO);
                wxMpService.getKefuService().sendKefuMessage(message);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "1";
    }

}
